﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace TetraEngine
{
    public abstract class Piece
    {
        private BlockGrid[] orientations;
        protected int rotationIndex = 0;

        protected Piece()
        {
            init();
        }
        private bool isInit=false;
        private void init()
        {
            if (isInit) return;
            InitializeOrientations(out this.orientations);
            isInit = true;
        }

        public BlockGrid GetBlockGrid()
        {
            init();
            while (rotationIndex < 0) rotationIndex += orientations.Length;
            return orientations[rotationIndex % orientations.Length];
        }

        public int RotationIndex
        {
            get { return rotationIndex; }
            set { rotationIndex = (value % orientations.Length); }
        }

        protected abstract void InitializeOrientations(
            out BlockGrid[] blockGrid);



        public override string ToString()
        {
            init();
            string s = "";
            for (int i = 0; i < orientations.Length; i++)
                s += orientations[i].ToString() + "\n";
            return s;
        }
    }

    public class SquarePiece : Piece
    {
        protected override void InitializeOrientations(out BlockGrid[] blockGrid)
        {
            blockGrid = new BlockGrid[1];
            blockGrid[0] = new BlockGrid(2);
            for (int i = 0; i < 2; i++)
                for (int j = 0; j < 2; j++)
                    blockGrid[0][i, j] = 3;
        }
    }
    public class ZPiece : Piece
    {
        protected override void InitializeOrientations(out BlockGrid[] blockGrid)
        {
            blockGrid = new BlockGrid[2];
            blockGrid[0] = new BlockGrid(3);
            blockGrid[0][0, 0] = 2;
            blockGrid[0][0, 1] = 2;
            blockGrid[0][1, 1] = 2;
            blockGrid[0][1, 2] = 2;
            blockGrid[1] = blockGrid[0].Copy();
            blockGrid[1].RotateCCW();
        }
    }
    public class SPiece : Piece
    {
        protected override void InitializeOrientations(out BlockGrid[] blockGrid)
        {
            blockGrid = new BlockGrid[2];
            blockGrid[0] = new BlockGrid(3);
            blockGrid[0][0, 0] = 4;
            blockGrid[0][1, 0] = 4;
            blockGrid[0][1, 1] = 4;
            blockGrid[0][2, 1] = 4;
            blockGrid[1] = blockGrid[0].Copy();
            blockGrid[1].RotateCCW();
        }
    }
    public class LinePiece : Piece
    {
        protected override void InitializeOrientations(out BlockGrid[] blockGrid)
        {
            blockGrid = new BlockGrid[2];
            blockGrid[0] = new BlockGrid(4);
            blockGrid[0][0, 1] = 5;
            blockGrid[0][1, 1] = 5;
            blockGrid[0][2, 1] = 5;
            blockGrid[0][3, 1] = 5;
            blockGrid[1] = blockGrid[0].Copy();
            blockGrid[1].RotateCCW();
        }
    }
    public class TPiece : Piece
    {
        protected override void InitializeOrientations(out BlockGrid[] blockGrid)
        {
            blockGrid = new BlockGrid[4];
            blockGrid[0] = new BlockGrid(3);
            blockGrid[0][0, 1] = 6;
            blockGrid[0][1, 0] = 6;
            blockGrid[0][1, 1] = 6;
            blockGrid[0][2, 1] = 6;
            for (int i = 1; i < 4; i++)
            {
                blockGrid[i] = blockGrid[i - 1].Copy();
                blockGrid[i].RotateCCW();
            }
        }
    }
    public class LPiece : Piece
    {
        protected override void InitializeOrientations(out BlockGrid[] blockGrid)
        {
            blockGrid = new BlockGrid[4];
            blockGrid[0] = new BlockGrid(3);
            blockGrid[0][0, 1] = 7;
            blockGrid[0][1, 1] = 7;
            blockGrid[0][2, 1] = 7;
            blockGrid[0][2, 2] = 7;
            for (int i = 1; i < 4; i++)
            {
                blockGrid[i] = blockGrid[i - 1].Copy();
                blockGrid[i].RotateCCW();
            }
        }
    }
    public class JPiece : Piece
    {
        protected override void InitializeOrientations(out BlockGrid[] blockGrid)
        {
            blockGrid = new BlockGrid[4];
            blockGrid[0] = new BlockGrid(3);
            blockGrid[0][0, 1] = 1;
            blockGrid[0][1, 1] = 1;
            blockGrid[0][2, 1] = 1;
            blockGrid[0][2, 0] = 1;
            for (int i = 1; i < 4; i++)
            {
                blockGrid[i] = blockGrid[i - 1].Copy();
                blockGrid[i].RotateCCW();
            }
        }
    }
}
